TypeScript 与 Node.js 教程

1. 简介

1.1 Node.js 简介

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境,它允许开发者使用 JavaScript 编写服务器端应用程序。Node.js 以其非阻塞 I/O 和事件驱动模型而闻名,使其非常适合构建高性能的网络应用。

1.2 TypeScript 简介

TypeScript 是 JavaScript 的一个超集,添加了静态类型检查和其他一些高级特性。TypeScript 编译器会将 TypeScript 代码转换为纯 JavaScript 代码,使其可以在任何支持 JavaScript 的环境中运行。

2. 环境搭建

2.1 安装 Node.js

首先,你需要在你的机器上安装 Node.js。你可以从 Node.js 官方网站 下载并安装适合你操作系统的版本。

2.2 安装 TypeScript

安装 Node.js 后,你可以使用 npm(Node 包管理器)来安装 TypeScript:

npm install -g typescript

2.3 版本管理(nvm)

为了方便管理 Node.js 的不同版本,你可以使用 nvm(Node Version Manager)。安装 nvm 后,你可以轻松地在不同版本的 Node.js 之间切换。

# 安装 nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash

# 使用 nvm 安装 Node.js
nvm install 14
nvm use 14

3. 创建第一个 TypeScript 与 Node.js 应用

3.1 初始化项目

首先,创建一个新的项目目录并初始化 npm:

mkdir my-node-app
cd my-node-app
npm init -y

3.2 安装依赖

接下来,安装 TypeScript 和 Node.js 的类型定义:

npm install --save-dev typescript @types/node

3.3 配置 TypeScript

创建一个 tsconfig.json 文件来配置 TypeScript 编译器:

{
  "compilerOptions": {
    "target": "ES6",
    "module": "CommonJS",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true
  },
  "include": ["src/**/*"]
}

3.4 编写代码

在 src 目录下创建一个 index.ts 文件,并编写一些简单的代码:

// src/index.ts
import * as http from 'http';

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello, World!\n');
});

const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
  console.log(`Server running at http://localhost:${PORT}/`);
});

3.5 编译和运行

使用 TypeScript 编译器将 TypeScript 代码编译为 JavaScript:

npx tsc

编译完成后,你可以在 dist 目录下找到生成的 JavaScript 文件。然后,使用 Node.js 运行生成的 JavaScript 文件:

node dist/index.js

打开浏览器访问 http://localhost:3000/,你应该会看到 "Hello, World!" 的输出。

4. 模块系统

4.1 CommonJS 模块

Node.js 默认使用 CommonJS 模块系统。你可以使用 require 和 module.exports 来导入和导出模块。

// math.js
module.exports = {
  add: (a, b) => a + b,
  subtract: (a, b) => a - b
};

// index.js
const math = require('./math');
console.log(math.add(2, 3)); // 输出: 5

4.2 ES Modules

从 Node.js 12 开始,你可以使用 ES 模块(ESM)。你需要在 package.json 中添加 "type": "module",或者使用 .mjs 扩展名。

// math.mjs
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;

// index.mjs
import { add } from './math.mjs';
console.log(add(2, 3)); // 输出: 5

5. 包管理器

5.1 npm

npm 是 Node.js 的默认包管理器。你可以使用 npm install 来安装依赖包。

npm install express

5.2 yarn

yarn 是另一个流行的包管理器,它提供了更快的安装速度和更可靠的依赖管理。

yarn add express

6. 事件循环和异步编程

6.1 事件循环

Node.js 的事件循环是其非阻塞 I/O 的核心。事件循环允许 Node.js 处理大量并发连接,而不会阻塞主线程。

6.2 异步编程

Node.js 提供了多种异步编程模式:

6.2.1 回调函数

回调函数是 Node.js 中最基本的异步编程模式。

const fs = require('fs');

fs.readFile('file.txt', 'utf8', (err, data) => {
  if (err) throw err;
  console.log(data);
});

6.2.2 Promise

Promise 是 ES6 引入的一种更现代的异步编程模式。

const fs = require('fs').promises;

fs.readFile('file.txt', 'utf8')
  .then(data => console.log(data))
  .catch(err => console.error(err));

6.2.3 async/await

async/await 是基于 Promise 的语法糖,使异步代码看起来更像同步代码。

const fs = require('fs').promises;

async function readFile() {
  try {
    const data = await fs.readFile('file.txt', 'utf8');
    console.log(data);
  } catch (err) {
    console.error(err);
  }
}

readFile();

7. 流(Streams)和缓冲区(Buffers)

7.1 流

流是 Node.js 中处理数据的一种方式,特别适合处理大文件或网络数据。

const fs = require('fs');

const readStream = fs.createReadStream('file.txt', 'utf8');
const writeStream = fs.createWriteStream('output.txt');

readStream.on('data', chunk => {
  writeStream.write(chunk);
});

readStream.on('end', () => {
  console.log('File copied successfully');
});

7.2 缓冲区

缓冲区是 Node.js 中处理二进制数据的一种方式。

const buffer = Buffer.from('Hello, World!', 'utf8');
console.log(buffer.toString('utf8')); // 输出: Hello, World!

8. 文件系统操作

Node.js 提供了丰富的文件系统操作 API。

const fs = require('fs');

// 读取文件
fs.readFile('file.txt', 'utf8', (err, data) => {
  if (err) throw err;
  console.log(data);
});

// 写入文件
fs.writeFile('output.txt', 'Hello, World!', err => {
  if (err) throw err;
  console.log('File written successfully');
});

9. 网络编程

9.1 HTTP 模块

Node.js 内置了 http 模块,可以用来创建 HTTP 服务器和客户端。

const http = require('http');

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello, World!\n');
});

server.listen(3000, () => {
  console.log('Server running at http://localhost:3000/');
});

9.2 HTTPS 模块

https 模块用于创建 HTTPS 服务器。

const https = require('https');
const fs = require('fs');

const options = {
  key: fs.readFileSync('key.pem'),
  cert: fs.readFileSync('cert.pem')
};

const server = https.createServer(options, (req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello, Secure World!\n');
});

server.listen(443, () => {
  console.log('Server running at https://localhost/');
});

10. Express.js 框架入门

Express.js 是一个流行的 Node.js 框架,用于构建 Web 应用程序和 API。

10.1 安装 Express.js

npm install express

10.2 创建一个简单的 Express 应用

const express = require('express');
const app = express();
const PORT = 3000;

app.get('/', (req, res) => {
  res.send('Hello, World!');
});

app.listen(PORT, () => {
  console.log(`Server running at http://localhost:${PORT}/`);
});

11. 路由和中间件

11.1 路由

路由用于定义应用程序的端点(URL)以及如何响应客户端请求。

app.get('/users', (req, res) => {
  res.send('List of users');
});

app.post('/users', (req, res) => {
  res.send('User created');
});

11.2 中间件

中间件是 Express.js 中用于处理请求和响应的函数。

app.use((req, res, next) => {
  console.log('Time:', Date.now());
  next();
});

12. 模板引擎

12.1 EJS

EJS 是一个简单的模板引擎,允许你在 HTML 中嵌入 JavaScript 代码。

npm install ejs
app.set('view engine', 'ejs');

app.get('/', (req, res) => {
  res.render('index', { title: 'My App' });
});

12.2 Pug

Pug 是一个高性能的模板引擎,语法简洁。

npm install pug
app.set('view engine', 'pug');

app.get('/', (req, res) => {
  res.render('index', { title: 'My App' });
});

13. RESTful API 设计和实现

13.1 设计 RESTful API

RESTful API 是一种基于 HTTP 协议的 API 设计风格,使用标准的 HTTP 方法(GET, POST, PUT, DELETE)来操作资源。

13.2 实现 RESTful API

const express = require('express');
const app = express();
const PORT = 3000;

let users = [];

app.use(express.json());

app.get('/users', (req, res) => {
  res.json(users);
});

app.post('/users', (req, res) => {
  const user = req.body;
  users.push(user);
  res.status(201).json(user);
});

app.listen(PORT, () => {
  console.log(`Server running at http://localhost:${PORT}/`);
});

14. 身份认证和授权

14.1 基本认证

基本认证是一种简单的身份验证方法,通常用于测试和开发环境。

app.use((req, res, next) => {
  const auth = { login: 'admin', password: 'password' };
  const b64auth = (req.headers.authorization || '').split(' ')[1] || '';
  const [login, password] = Buffer.from(b64auth, 'base64').toString().split(':');

  if (login && password && login === auth.login && password === auth.password) {
    return next();
  }

  res.set('WWW-Authenticate', 'Basic realm="401"');
  res.status(401).send('Authentication required.');
});

14.2 JWT 认证

JWT(JSON Web Token)是一种更安全的认证方法,常用于生产环境。

npm install jsonwebtoken
const jwt = require('jsonwebtoken');

const SECRET_KEY = 'your-secret-key';

app.post('/login', (req, res) => {
  const user = req.body;
  const token = jwt.sign(user, SECRET_KEY);
  res.json({ token });
});

app.get('/protected', (req, res) => {
  const token = req.headers['authorization'];
  if (!token) return res.status(401).send('Token required');

  jwt.verify(token, SECRET_KEY, (err, decoded) => {
    if (err) return res.status(401).send('Invalid token');
    res.json(decoded);
  });
});

15. SQL 数据库

15.1 MySQL

MySQL 是一个流行的关系型数据库管理系统。

npm install mysql
const mysql = require('mysql');

const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'mydb'
});

connection.connect();

connection.query('SELECT * FROM users', (err, rows) => {
  if (err) throw err;
  console.log(rows);
});

connection.end();

15.2 PostgreSQL

PostgreSQL 是一个功能强大的开源关系型数据库。

npm install pg
const { Client } = require('pg');

const client = new Client({
  user: 'root',
  host: 'localhost',
  database: 'mydb',
  password: 'password',
  port: 5432,
});

client.connect();

client.query('SELECT * FROM users', (err, res) => {
  if (err) throw err;
  console.log(res.rows);
  client.end();
});

16. NoSQL 数据库

16.1 MongoDB

MongoDB 是一个流行的 NoSQL 数据库,使用文档存储数据。

npm install mongodb
const { MongoClient } = require('mongodb');

const uri = 'mongodb://localhost:27017';
const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });

client.connect(err => {
  if (err) throw err;
  const collection = client.db('mydb').collection('users');
  collection.find({}).toArray((err, docs) => {
    if (err) throw err;
    console.log(docs);
    client.close();
  });
});

17. ORM 和 ODM

17.1 Sequelize

Sequelize 是一个流行的 ORM(对象关系映射)库,支持多种 SQL 数据库。

npm install sequelize
npm install mysql2
const { Sequelize, DataTypes } = require('sequelize');

const sequelize = new Sequelize('mydb', 'root', 'password', {
  host: 'localhost',
  dialect: 'mysql'
});

const User = sequelize.define('User', {
  name: DataTypes.STRING,
  email: DataTypes.STRING
});

sequelize.sync().then(() => {
  User.findAll().then(users => {
    console.log(users);
  });
});